using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SovaDataService.SovaDataServices;
using System.Linq;
using SovaDataService.SoDataServices;
using SovaWebService.ViewModels;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using SovaDataService.SovaModels;
using System;
using System.Collections;

namespace SovaWebService.Controllers
{
    [Route("api/marked_questions")]
    public class MarkedQuestionsController : Controller
    {
        private readonly MarkedQuestionDataService _markedQuestionsDataService;
        private readonly QuestionDataService _questionsDataService;

        /**
         * Main constructor.
         */
        public MarkedQuestionsController
        (MarkedQuestionDataService markedQuestionsDataService, QuestionDataService questionDataService)
        {
            _markedQuestionsDataService = markedQuestionsDataService;
            _questionsDataService = questionDataService;
        }

        /**
         * Retrieves the marked questions with pagesize and pagination.
         */
        [Authorize]
        [HttpGet(Name = nameof(GetMarkedQuestions))]
        public IActionResult GetMarkedQuestions(int page = 0, int pageSize = 10)
        {
            int.TryParse(HttpContext.User.Identity.Name, out var userId);
            var markedQuestions = _markedQuestionsDataService.GetMarkedQuestionsForUser(userId).ToList();

            int[] markedQuestionIds = new int[markedQuestions.Count()];
            for (int i = 0; i < markedQuestions.Count(); i++)
            {
                markedQuestionIds[i] = markedQuestions[i].QuestionId;
            }

            var questions = _questionsDataService.GetAll(markedQuestionIds)
                .Skip(page * pageSize)
                .Take(pageSize);
            int total = _markedQuestionsDataService.GetCount(userId);

            var questionsList = new QuestionsListVM()
            {
                Total = total,
            };

            questionsList.Questions = new List<IQuestionVM>();
            foreach (var question in questions)
            {
                questionsList.Questions.Add(new MarkedQuestionVM()
                {
                    Title = question.Title,
                    Score = question.Score, 
                    QuestionUrl = Url.Link(nameof(QuestionsController.GetQuestion), new { id = question.Id }),
                    Body = question.Body,
                    AuthorName = question.Author.Name,
                    Annotation = markedQuestions.SingleOrDefault(mq => mq.QuestionId == question.Id).Annotation
                });
            }

            // Adding pagination properties to the object.
            questionsList += UrlHelper.Pagination(Url, nameof(GetMarkedQuestions), page, pageSize, total);

            return Ok(questionsList);
        }

        /**
         * Mark a question based on post body data.
         * questionId and possible annotation should be in the body data.
         */
        [Authorize]
        [HttpPost]
        public IActionResult MarkQuestion([FromBody] JObject data)
        {
            if (!data.ContainsKey("questionId"))
                return BadRequest();

            MarkedQuestion markedQuestion = new MarkedQuestion();
            bool validId = int.TryParse(data.GetValue("questionId").ToString(), out int questionId);
            if (!validId)
                return BadRequest();

            var question = _questionsDataService.GetOne(questionId);
            if (question == null)
                return BadRequest();

            markedQuestion.QuestionId = question.Id;

            if (data.ContainsKey("annotation"))
            {
                string annotation = data.GetValue("annotation").ToString();
                if (!string.IsNullOrWhiteSpace(annotation))
                {
                    markedQuestion.Annotation = annotation;
                }
            }

            int.TryParse(HttpContext.User.Identity.Name, out var userId);
            markedQuestion.AccountId = userId;

            var createdMarkedQuestion = _markedQuestionsDataService.Create(markedQuestion);

            if (createdMarkedQuestion == null)
                return BadRequest();

            string link = Url.Link(nameof(QuestionsController.GetQuestion), new { id = createdMarkedQuestion.QuestionId });

            return Created(link, createdMarkedQuestion);
        }

        /**
         * Removes the marked question by it's id.
         */
        [Authorize]
        [HttpDelete("{id}")]
        public IActionResult DeleteMarkedQuestion(int id)
        {
            int.TryParse(HttpContext.User.Identity.Name, out var userId);

            bool success = _markedQuestionsDataService.Delete(id, userId);
            if (!success)
                return BadRequest();

            return Ok();
        }
    
    }
}